package com.dragon.app.concurrent;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 
 * <p>class: SpinLockTest</p>  
 * <p>Description: 手动实现自旋锁，使用cas</p>  
 * @author SmallDragon
 * @date 2019年5月6日
 *
 */
public class SpinLockTest {

	AtomicReference<Thread> reference = new AtomicReference<>(null);

	public void lock() {
		Thread currentThread = Thread.currentThread();
		System.out.println(currentThread.getName() + " is coming...");
		
		//获取锁
		while (!reference.compareAndSet(null, currentThread)) {
		}
		
		System.out.println(currentThread.getName() + " => get the lock success");
	}

	public void unlock() {
		Thread currentThread = Thread.currentThread();
		
		//释放锁
		reference.compareAndSet(currentThread, null);
		
		System.out.println(currentThread.getName() + " => release the lock");
	}

	public static void main(String[] args) {

		SpinLockTest spinLockTest = new SpinLockTest();

		new Thread(() -> {
			spinLockTest.lock();
			try {
				TimeUnit.SECONDS.sleep(3);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			spinLockTest.unlock();
		}, "thread-AAA").start();
		
		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		new Thread(() -> {
			spinLockTest.lock();
			try {
				TimeUnit.SECONDS.sleep(3);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			spinLockTest.unlock();
		}, "thread-BBB").start();

	}

}
